<?php

namespace Common\Logic;

use Think\Exception;

/**
 * 团购逻辑
 * 
 */ 
class GroupbuyLogic 
{

    const USER_TABLE = "users";

    const GOODS_TABLE = "goods";

    const GROUPBUY_TABLE = "group_buy";

    const GROUP_INFO_TABLE = "group_info";

    const GROUP_ORDER_TABLE = "group_order";

    const ORDER_TABLE = "order";

    const ORDERGOODS_TABLE = "order_goods";

    const ADDRESS_TABLE = "user_address";

    const GOODS_SPEC_TABLE = "spec_goods_price";

    // 订单过期时间 s
    const ORDER_EXPIRE_IN = 1800;

    /**
     * 获取团购商品列表
     * @param $p 
     * @param $shop_id int 默认全部 
     * @param $simple 显示简单信息
     * @return mix 
     */
    public static function getGoodsList($param,$simple = true)
    {
        $model = M(self::GROUPBUY_TABLE);

        $now = time();

        $where = [
            "status" => 1,
            "start_time" => ["lt",$now],
            "end_time" => ["gt",$now],
        ];

        if( isset($param['shop_id']) )
        {
            $where['shop_id'] = $param['shop_id'];
        }

        $count = $model->where($where)->count();
        $Page = new \Think\Page($count,10);

        if( $simple )
        {
            $list = $model->where($where)
            ->field("id,title,start_time,end_time,goods_id,goods_name,price,goods_price as shop_price")
            ->order("recommended desc,create_time desc")
            ->limit($Page->firstRow.','.$Page->listRows)
            ->select();
        }else{
            $list = $model->where($where)
            ->order("recommended desc,create_time desc")
            ->limit($Page->firstRow.','.$Page->listRows)
            ->select();
        }
        $goodsModel = M(self::GOODS_TABLE);
        foreach($list as $k => &$v)
        {
            $v['good_specs'] = json_decode($v['good_specs'],true);
            $v['good_specs'] = $v['good_specs'] ? $v['good_specs'] : [];

            $original_img = $goodsModel->where([
                "goods_id" => $v['goods_id']
            ])->field("original_img")->cache(300)->find();

            $v['original_img'] = $original_img['original_img'] ? parseMediaUrl($original_img['original_img']) : "";

            $v['goods_num'] = $v['goods_num'] - $v['buy_num'];
        } 

        return [
            "total" => $count,
            "list" => $list
        ];
    }

    /**
     * 获取团购商品详情
     * @param $groupbuy_id int 团购id
     * @param $user_id int 默认0
     * @return  bool/mix
     **/ 
    public static function getDetailForGoods($param)
    {
        if( !$param || !isset($param['groupbuy_id']) )
        {
            throw new Exception("参数错误",-1);
        }

        $groupbuy_id = $param['groupbuy_id'];

        $user_id = isset($param['user_id']) ? $param['user_id'] : 0;

        $groupgoods = M(self::GROUPBUY_TABLE)->where([
            "id" => $groupbuy_id,
            "start_time" => ["lt",time()],
            "end_time" => ["gt",time()]
        ])->find();

        if( !$groupgoods )
            throw new Exception("商品已下架",-1);
        
        $goods_id = $groupgoods['goods_id'];
        
        $groupgoods['good_specs'] = json_decode( $groupgoods['good_specs'], true );

        $groupgoods['good_specs'] = $groupgoods['good_specs'] ? $groupgoods['good_specs'] : [];
        
         

        #获取商品的元信息
        $goods = M(self::GOODS_TABLE)->where([
            "goods_id" => $goods_id
        ])->find();

        if( empty($goods) || empty($goods['is_on_sale']) )
            throw new Exception("商品已下架",-2);

        $goods['collect_num'] = $goods['collect_num'] ? $goods['collect_num'] : 0;
        $is_collect = M('GoodsCollect')->where("user_id=$user_id and goods_id=$goods_id")->find();
        if (empty($is_collect)) {
           $goods['is_collect'] = 0;
        }else{
            $goods['is_collect'] = 1;
        }
        // 处理商品规格
        
        // 商品规格 价钱 库存表 找出 所有 规格项id
        $goods['goods_attr_list'] = M('GoodsAttr as g')
                        ->field('ga.attr_id,ga.attr_name,g.attr_value')
                        ->join('ln_goods_attribute as ga on ga.attr_id=g.attr_id')
                        ->where("goods_id = $goods_id")
                        ->select();
        $goods['goods_spec_list'] = [];
        $spec_goods_price = [];
        if($groupgoods['good_specs'])
        {
            $specImage = M('SpecImage')->where("goods_id = $goods_id and src != '' ")->getField("spec_image_id,src");// 规格对应的 图片表， 例如颜色
            #多规格以团购为准
            $keys = [];
            foreach($groupgoods['good_specs'] as $k => $v )
            {
                $keys = array_merge($keys, explode("_",$k) );
                $spec_goods_price[] = [
                    "key" => $k,
                    "price" => $v['price'],
                    "store_count" => $v['num']
                ];
            }
            $groupgoods['good_specs'] = [];
            $keys = array_unique($keys);
            $keys = implode(',',$keys);
            $filter_spec2 = M("SpecItem")->alias("a")
                            ->join("ln_spec AS b ON b.id = a.spec_id")
                            ->where([
                                "a.id" => ["IN",$keys]
                            ])
                            ->field("b.name,b.order,a.*")
                            ->order("a.spec_id,b.id")
                            ->fetchSql(0)
                            ->select();
            $filter_spec = [];
            foreach($filter_spec2 as $val){
                if(!array_key_exists($val['name'],$filter_spec)){
                    $filter_spec[$val['name']]['name'] = $val['name'];
                }
                $filter_spec[$val['name']]['values'][] = [
                    'item'=> $val['item'],
                    'item_id'=> $val['id'],
                    'src' =>$specImage[$val['id']] ? parseMediaUrl($specImage[$val['id']]) : ''
                ];
            }

            $goods_spec_list = array_values($filter_spec);
            $goods['goods_spec_list'] = $goods_spec_list?$goods_spec_list:array();
            
        }

        $goods['goods_content'] = parseRichTextContent($goods['goods_content']);
        $goods['original_img'] = parseMediaUrl($goods['original_img']);
        //获取实际评论数
        $goods['comment_count'] = M('comment')->where("goods_id={$goods_id} AND is_show=1 AND parent_id=0")->count();
        
        #商品价格改为团购价,库存改成团购量
        // $goods['shop_price'] = $groupgoods['price'];
        // $goods['store_count'] = $groupgoods['goods_num'];

        $gallery = M('goods_images')->field('image_url')->where(array('goods_id'=>$goods_id))->select();
        foreach($gallery as $key => &$val){
           $val['image_url'] = parseMediaUrl($val['image_url']);
        }
        
        $goodsLogic = new \Home\Logic\GoodsLogic();
        $add_update_info = $goodsLogic->addgoodsView($user_id, $goods_id);
        
        #增加浏览量
        M(self::GROUPBUY_TABLE)->where([
            "id" => $groupbuy_id
        ])->save([
            "views" => ["exp","views+1"],
            "update_time" => time()
        ]);
        
        //获取最近的两条评论
        $latest_comment = M('comment')->where("goods_id={$goods_id} AND is_show=1 AND parent_id=0")->limit(2)->select();
        foreach($latest_comment as $k => &$v)
        {
            $v['img'] = unserialize($v['img']);
            if(!empty($v['img']))
            {
                foreach($v['img'] as &$item)
                {
                    $item = parseMediaUrl($item);
                }
            }else{
                $v['img'] = [];
            }
        }
        #获取参团的团信息
        $group_users_id = M(self::GROUP_ORDER_TABLE)
        ->field("DISTINCT user_id")
        ->where([
            "group_buy_id" => $groupbuy_id,
            "status" => 1
        ])->order("create_time desc")->limit(3)->select();
        $group_users = [];
        foreach($group_users_id as $user_v)
        {
            $user_v = M('users')->where([
                "user_id" => $user_v['user_id']
            ])->field("user_id,head_pic,nickname")->find();
            if( $user_v )
            {
                $user_v['head_pic'] = parseMediaUrl($user_v['head_pic']);
                $group_users[] = $user_v;
            }
        }
        
        #计算差几人成团
        $newGroupInfo = M(self::GROUP_INFO_TABLE)
        ->where([
            "group_buy_id" => $groupbuy_id,
        ])->order("create_time desc")->find();

        if( $newGroupInfo )
        {
            $groupgoods['dirt_num'] = $newGroupInfo['per_num'] - $newGroupInfo['member_num'];
            $groupgoods['dirt_num'] =  $groupgoods['dirt_num'] > 0 ?  $groupgoods['dirt_num']:$groupgoods['per_num'];
        }else{
            $groupgoods['dirt_num'] = $groupgoods['per_num'];
        }

        #合并商品信息，多规格以团购为准
        $groupgoods['group_users'] = $group_users;
        #团购商品价格显示为团购价
        // $groupgoods['goods_price'] = $groupgoods['price'];

        // 输出客服
        $shop_kefu = ''; 
        $shop = M('shop')->where([
            "id" => $goods['shop_id']
        ])->field('id as shop_id,user_id')->find();
        if( $shop )
        $shop_kefu = $shop['user_id'];
        $shop_kefu_info = M('users')->where([
            'user_id' => $shop['user_id']
        ])->field('user_id,nickname,head_pic')->find();
        if( $shop_kefu_info )
        {
            $shop_kefu_info['head_pic'] = \parseMediaUrl($shop_kefu_info['head_pic'] );
        }else{
            $shop_kefu_info = '';
        }
        $result = [
            "shop_kefu" => $shop_kefu,
            "shop_kefu_info" => $shop_kefu_info,
            "comment" => $latest_comment ? $latest_comment : [],
            "gallery" => $gallery ? $gallery : [],
            "goods" => $goods,
            "groupgoods" => $groupgoods,
            "spec_goods_price" => $spec_goods_price
        ];
        
        return $result;
    }

    /**
     * 获取团信息
     * @param $user_id 非必填
     * @param $groupbuy_id 非必填
     * @param $order_sn 非必填
     * @param $group_status 默认0待成团 1已成团 2已解散
     * @return mix
     */ 
    public static function getGroupItem($param = [],$group_status = 0)
    {

        $where = [
            "b.status" => $group_status
        ];

        if( isset($param['user_id']) )
        {
            $where['a.user_id'] = $param['user_id'];
        }

        if( isset($param['groupbuy_id']) )
        {
            $where['a.group_buy_id'] = $param['groupbuy_id'];
        }

        if( isset($param['order_sn']) )
        {
            $where['a.order_sn'] = $param['order_sn'];
        }

        $res = M(self::GROUP_ORDER_TABLE)
            ->alias("a")
            ->join("ln_".self::GROUP_INFO_TABLE." as b on a.group_info_id = b.id")
            ->where($where)->order("a.create_time desc")
            ->select();
        foreach($res as $k => &$v)
        {
            $group_user = M(self::GROUP_ORDER_TABLE)->where([
                "group_info_id" => $v['group_info_id']
            ])->order('create_time asc')->find();
            $v['group_user'] = M('users')->where([
                "user_id" => $group_user['user_id']
            ])->field("user_id,nickname,head_pic")->find();
            $v['dirt_num'] = $v['per_num'] - $v['member_num'];
        }
        
        return $res;
    }


    /**
     * 获取团购订单列表
     * @param $p 
     * @param $shop_id int 默认全部 
     * @param $pay_status int 默认全部 
     * @param $order_status int 默认全部 
     * @return mix 
     */
    public static function getGroupOrderList($param)
    {
        $model = M(self::ORDER_TABLE);

        $where = [
            "is_groupbuy" => 1
        ];

        if( isset($param['shop_id']) )
        {
            $where['shop_id'] = $param['shop_id'];
        }

        if( isset($param['pay_status']) )
        {
            $where['pay_status'] = $param['pay_status'];
        }

        if( isset($param['order_status']) )
        {
            $where['order_status'] = $param['order_status'];
        }

        $count = $model->where($where)->count();
        $Page = new \Think\Page($count,10);
        
        $list = $model->where($where)
            ->order("add_time desc")
            ->limit($Page->firstRow.','.$Page->listRows)
            ->select();

        return [
            "total" => $count,
            "list" => $list
        ];
    }

    /**
     * 选择数量和规格准备下单，和下单方法一致，不过去除了创建订单，事务回滚等
     * @param $user_id
     * @param $groupbuy_id
     * @param $spec_key string 规格key(多规格必填)
     * @param $num int 商品数量默认1
     * @return mix
     **/ 
    public static function preCreateOrder($param)
    {
        if( !isset($param['user_id']) || !isset($param['groupbuy_id']) )
            throw new Exception('参数错误',-1);
        
        $GroupBuy = M(self::GROUPBUY_TABLE);

        $item = $GroupBuy->where("id ={$param['groupbuy_id']}")->find();

        if( !$item || !$item['status'] )
        { 
            throw new Exception("商品不存在",-1);
        }
        

        $param['num'] = isset( $param['num'] ) ? intval( $param['num'] ) : 1;

        #订单信息
        $OrderInfo = [];

        $now = time();
        #检查时间
        if( $now < $item['start_time'] )
        { 
            throw new Exception("团购时间尚未开始",-1);
        }

        #检查时间
        if( $now > $item['end_time'] )
        { 
            throw new Exception("团购时间已经结束",-1);
        }
        
        #是否有未支付订单
        $payOrderModel = M(self::GROUP_ORDER_TABLE);

        $no_pay_order = $payOrderModel->where([
            "user_id" => $param['user_id'],
            "group_buy_id" => $param['groupbuy_id'],
            "status" => 0
        ])->find();

        if( $no_pay_order )
        { 
            throw new Exception("相同团购有未支付订单",0);
        }

        #是否限购
        if( $item['max_buy_num'] > 0 )
        {
            $user_buy_num = M(self::GROUP_ORDER_TABLE)->where([
                "group_buy_id" => $param['group_buy_id'],
                "user_id" => $param['user_id'],
                "status" => ["lt",2] #必须这样，防止利用漏洞
            ])->sum("goods_num");

            if( $user_buy_num + $param['num'] > $item['max_buy_num'] )
            { 
                throw new Exception("已经到达商品限购数",-1);
            }
        }

        #检查是否多规格
        /*$item['good_specs'] = json_decode($item['good_specs'],true);
        if( !empty($item['good_specs']) )
        {
            if( !isset($param['spec_key']) || empty($param['spec_key']) )
            { 
                throw new Exception("未选择商品规格",-1);
            }

            if( !isset($item['good_specs'][$param['spec_key']]) )
            { 
                throw new Exception("选择的商品规格无效",-1);
            }

            $spec_info = $item['good_specs'];
            $item_spec = $spec_info[$param['spec_key']];
            $item_spec['buy_num'] = isset($item_spec['buy_num']) ? $item_spec['buy_num'] : 0;

            if( $param['num'] > $item_spec['num'] - $item_spec['buy_num'] )
            {
                M()->rollback();
                throw new Exception("所选规格商品库存不足",-1);
            }

            $updateGroupSql = [
                "buy_num" => ["exp","buy_num+".$param['num']]
            ];

            $item_spec['buy_num'] = $item_spec['buy_num'] + $param['num'];
            $spec_info[$param['spec_key']] = $item_spec;

            $updateGroupSql['good_specs'] = json_encode( $spec_info );

        }else{*/

            $param['spec_key'] = "";

            if( $param['num'] > $item['goods_num'] - $item['buy_num'] )
            { 
                throw new Exception("库存不足",-1);
            }

            $updateGroupSql = [
                "buy_num" => ["exp","buy_num+".$param['num']],
            ];
        /*}*/

        #获取原商品信息
        $goods_info = M(self::GOODS_TABLE)
        ->where([
            "goods_id" => $item['goods_id']
        ])->find();

        if( !$goods_info || !$goods_info['is_on_sale'] )
            throw new Exception("商品已下架",-5);

        #计算商品价格
        $goods_price = self::genratePayOrder([
            "groupBuyInfo" => $item,
            "spec_key" => $param['spec_key'],
            "num" => $param['num'],
            "user_id" => $param['user_id']
        ],true);

        #看看有没默认地址，计算快递费
        $addresslist = M('UserAddress')
        ->where(["user_id"=>$param['user_id']])
        ->order("is_default desc")
        ->limit(1)
        ->fetchSql(0)
        ->select();

        #cartList
        #获取商店信息
        $shop_info = M('shop')
        ->field('id,shop_name,shop_head_img')
        ->where(array('id' => $item['shop_id']))
        ->find();

        $cartList = [];
        $goods_info['goods_price'] = $item['price'];
        $goods_info['goods_num'] = $param['num'];
        $goods_info['original_img'] = parseMediaUrl($goods_info['original_img']);

        #totalPrice
        #postfee 
        $post_fee = self::getShipingPrice( $goods_info['goods_id'], $param['num'], $goods_price );

        $total_price = array(
            'total_fee' => $goods_price + $post_fee, //加上快递费给前端显示
            'post_fee' => $post_fee, 
            'cut_fee' => bcmul( $param['num'], bcsub($item['goods_price'] , $item['price'], 2 ) ,2) , 
            'num' => $param['num'], 
            'market_cut_fee' => bcmul( $param['num'], bcsub($goods_info['market_price'] , $item['price'], 2 ) ,2) , 
        ); // 总计

        $cartList[0] = [
            "shop_id" => $shop_info['id'],
            "selected" => 1,
            "shop_name" => $shop_info['shop_name'],
            "shop_head_img" => parseMediaUrl($shop_info['shop_head_img']),
            "total_price" => $total_price,
            'available_points' => 0,//账户可用积分
            'all_pay_point' => 0,//需用的积分
            'integral_money' => 0,//积分抵扣金额
            "cartList" => [
                $goods_info
            ]
        ];

        

        #couponList 团购不能使用优惠券
        

        #返回需要支付的钱以及商品信息
        
        return [
            "addressList" => $addresslist,
            "cartList"  =>  $cartList,
            "totalPrice"  => $total_price,
            "couponList"  => [],
            'available_points' => 0,//账户可用积分
            'all_pay_point' => 0,//需用的积分
            'integral_money' => 0,//积分抵扣金额
        ];
    }

    /**
     * 下单
     * 预先扣除相应的团购库存，然后在15分钟之内如果没有支付，再把订单作废
     * @param $user_id int 用户id
     * @param $groupbuy_id int 团购id
     * @param $spec_key string 规格key(多规格必填)
     * @param $num int 商品数量默认1
     * @param $address_id int 地址id
     * @param $invoice_title string 发票抬头
     * @param $user_note string 用户备注
     * @return mix
     */ 
    public static function createOrder($param)
    {
        if( !isset($param['user_id']) || !isset($param['groupbuy_id']) )
        throw new Exception('参数错误',-1);

        if( !isset($param['address_id']) || empty($param['address_id']) )
        throw new Exception('未选择收货地址',-1);

        M()->startTrans();

        $GroupBuy = M(self::GROUPBUY_TABLE);

        $item = $GroupBuy->where("id ={$param['groupbuy_id']}")->find();

        if( !$item || !$item['status'] )
        {
            M()->rollback();
            throw new Exception("商品不存在",-1);
        }
        

        $param['num'] = isset( $param['num'] ) ? intval( $param['num'] ) : 1;

        #订单信息
        $OrderInfo = [];

        $now = time();
        #检查时间
        if( $now < $item['start_time'] )
        {
            M()->rollback();
            throw new Exception("团购时间尚未开始",-1);
        }

        #检查时间
        if( $now > $item['end_time'] )
        {
            M()->rollback();
            throw new Exception("团购时间已经结束",-1);
        }

        #是否有未支付订单
        $payOrderModel = M(self::GROUP_ORDER_TABLE);

        $no_pay_order = $payOrderModel->where([
            "user_id" => $param['user_id'],
            "group_buy_id" => $param['groupbuy_id'],
            "status" => 0
        ])->find();

        if( $no_pay_order )
        {
            M()->rollback();
            throw new Exception("相同团购有未支付订单",0);
        }

        #是否限购
        if( $item['max_buy_num'] > 0 )
        {
            $user_buy_num = M(self::GROUP_ORDER_TABLE)->where([
                "group_buy_id" => $param['group_buy_id'],
                "user_id" => $param['user_id'],
                "status" => ["lt",2] #必须这样，防止利用漏洞
            ])->sum("goods_num");

            if( $user_buy_num + $param['num'] > $item['max_buy_num'] )
            {
                M()->rollback();
                throw new Exception("已经到达商品限购数",-1);
            }
        }

        #检查是否多规格
        $item['good_specs'] = json_decode($item['good_specs'],true);
        if( !empty($item['good_specs']) )
        {
            if( !isset($param['spec_key']) || empty($param['spec_key']) )
            {
                M()->rollback();
                throw new Exception("未选择商品规格",-1);
            }

            if( !isset($item['good_specs'][$param['spec_key']]) )
            {
                M()->rollback();
                throw new Exception("选择的商品规格无效",-1);
            }

            $spec_info = $item['good_specs'];
            $item_spec = $spec_info[$param['spec_key']];
            $item_spec['buy_num'] = isset($item_spec['buy_num']) ? $item_spec['buy_num'] : 0;

            if( $param['num'] > $item_spec['num'] - $item_spec['buy_num'] )
            {
                M()->rollback();
                throw new Exception("所选规格商品库存不足",-1);
            }

            $updateGroupSql = [
                "buy_num" => ["exp","buy_num+".$param['num']]
            ];
            
            $item_spec['buy_num'] = $item_spec['buy_num'] + $param['num'];
            $spec_info[$param['spec_key']] = $item_spec;

            $updateGroupSql['good_specs'] = json_encode( $spec_info );

        }else{

            $param['spec_key'] = "";

            if( $param['num'] > $item['goods_num'] - $item['buy_num'] )
            {
                M()->rollback();
                throw new Exception("库存不足",-1);
            }

            $updateGroupSql = [
                "buy_num" => ["exp","buy_num+".$param['num']],
            ];
        }

        #生成支付订单

        $param['invoice_title'] = isset($param['invoice_title']) ? $param['invoice_title'] :'';
        $param['user_note'] = isset($param['user_note']) ? $param['user_note'] :'';

        $payOrder = self::genratePayOrder([
            "groupBuyInfo" => $item,
            "spec_key" => $param['spec_key'],
            "num" => $param['num'],
            "user_id" => $param['user_id'],
            "address_id" => $param['address_id'],
            "invoice_title" => $param['invoice_title'],
            "user_note" => $param['user_note'],
        ]);

        if( !$payOrder )
        {
            M()->rollback();
            throw new Exception("订单生成失败",-1);
        }

        #生成团购订单
        $groupOrder = self::genrateGroupOrder([
            "groupBuyInfo" => $item,
            "orderInfo" => $payOrder,
            "spec_key" => $param['spec_key'],
            "num" => $param['num'],
            "user_id" => $param['user_id'],
        ]);

        if(  !$groupOrder )
        {
            M()->rollback();
            throw new Exception("订单生成失败",-2);
        }

        $updateGroup = $GroupBuy->where("id ={$param['groupbuy_id']}")->save($updateGroupSql);
        if( FALSE === $updateGroup )
        {
            M()->rollback();
            throw new Exception("订单生成失败",-3);
        }

        #订单生成成功，返回订单信息
        M()->commit();
        return $payOrder;

    }

    /**
     * 支付成功之后执行拼团
     * @param $order_sn string 订单号
     * @return mix
     */ 
    public static function join($order_sn)
    {
        if( empty($order_sn) )
            return ["status"=>0,"msg"=>"参数错误","data"=>""];

        M()->startTrans();

        $model = M(self::GROUP_ORDER_TABLE);

        $order = $model->where([
            "order_sn" => $order_sn
        ])->find();

        if( !$order )
            return ["status"=>0,"msg"=>"订单不存在","data"=>""];

        if( $order['status'] != 0 )
            return ["status"=>1,"msg"=>"订单已经处理过","data"=>""];

        #检查是否有未成团
        
        $infoModel = M(self::GROUP_INFO_TABLE);

        $group = $infoModel->where([
            "group_buy_id" => $order['group_buy_id'],
            "status" => 0,
            "end_time" => ["gt",time()]
        ])->find();
        
        if( $group && $group['per_num'] > $group['member_num'] )
        {
             
            $update = [];

            $update['update_time'] = time();

            $update["member_num"] = ["exp","member_num+1"];

            if( $group['per_num'] == $group['member_num'] + 1 )
            {
                $update['status'] = 1;
            }

            #绑定团
            $join = $infoModel->where([
                "id" => $group['id'],
                "status" => 0
            ])->save($update);

            if( $join === false )
            {
                M()->rollback();
                return ["status"=>0,"msg"=>"加团处理失败","data"=>""];
            }
            
            #更改订单
            $groupOrder = $model->where([
                "id" => $order['id'],
                "group_info_id" => 0
            ])->save([
                "group_info_id" => $group['id'],
                "status" => 1,
                "join_group_time" => $update['update_time'],
                "update_time" => $update['update_time'],
            ]);

        }else{
            #需要开团
            
            #拉取团购活动信息
            $groupBuy = M(self::GROUPBUY_TABLE)->where([
                "id" => $order['group_buy_id']             
            ])->find();

            if( !$groupBuy )
            {
                return ["status"=>0,"msg"=>"团购活动不存在","data"=>""];
            }

            #创建团
            $newGroup = $infoModel->add([
                "group_buy_id" => $order['group_buy_id'],
                "per_num" => $groupBuy['per_num'],
                "end_time" => $groupBuy['end_time'],
                "member_num" => 1,
                "status" => 0,
                "create_time" => time(),
                "update_time" => time(),
            ]);

            if( $newGroup === false )
            {
                M()->rollback();
                return ["status"=>0,"msg"=>"开团处理失败","data"=>""];
            }

            #绑定团信息到订单
            #更改订单
            $groupOrder = $model->where([
                "id" => $order['id'],
                "group_info_id" => 0
            ])->save([
                "group_info_id" => $newGroup,
                "status" => 1,
                "join_group_time" => $update['update_time'],
                "update_time" => $update['update_time'],
            ]);
        }

        if( $groupOrder === false )
        {
            M()->rollback();
            return ["status"=>0,"msg"=>"订单绑定团处理失败","data"=>""];
        }

        M()->commit();
        return ["status"=>1,"msg"=>"处理成功","data"=>""];
    }

    /**
     * 系统订单关闭，回调关闭团购订单
     * @param order_sn
     * @return bool 
     */ 
    public static function closeGroupBuyOrderSn($order_sn)
    {
        $model = M(self::GROUP_ORDER_TABLE);

        $where = [
            "status" => 0,
            "order_sn" => $order_sn,
        ];

        $order = $model->where($where)->find();

        if( !$order )
        {
            return false;
        }

        $close_order = $model->where([
            "id" => $order['id']
        ])->save([
            "status" => 2,
            "update_time" => time()
        ]);

        #加库存
        $reback_store = self::rebackStore( $order );

        if( FALSE !== $close_order && $reback_store )
        {
            return true;
        }
        
        return false;
    }


    /**
     * 团购订单检查，把长时间未支付的订单关闭掉，支持关闭指定订单
     * @param $groupbuy_id int
     * @return mix
     */ 
    public static function closeGroupBuyOrder($groupbuy_id = NULL)
    {
        $model = M(self::GROUP_ORDER_TABLE);

        $where = [
            "status" => 0,
        ];

        if( $groupbuy_id )
        {
            $where['group_buy_id'] = $groupbuy_id;
        }else{
            $where['create_time'] = ["lt", time() - self::ORDER_EXPIRE_IN ];
        }

        $orders = $model->where($where)->select();

        if( empty($orders) )
        {
            return false;
        }

        $success = [];

        $orderModel = M(self::ORDER_TABLE);

        foreach($orders as $k => $v)
        {
            M()->startTrans();
            #逐个关闭系统订单和团购订单
            $close_order = $orderModel->where([
                "order_sn" => $v['order_sn']
            ])->save([
                "admin_note" => "超时关闭",
                "order_status" => 5
            ]);

            $close_group = $model->where([
                "id" => $v['id']
            ])->save([
                "status" => 2,
                "update_time" => time()
            ]);

            #加库存
            $reback_store = self::rebackStore( $v );

            if( FALSE !== $close_order && FALSE !== $close_group && $reback_store )
            {
                $success[] = $v['id'];
                M()->commit();
                continue;
            }

            M()->rollback();
            continue;
        }

        #加库存

        return $success;
    }

    /**
     * 恢复库存
     * @param \groupBuyOrder\groupBuyOrder
     */ 
    public static function rebackStore($groupBuyOrder)
    {

        if( empty($groupBuyOrder['spec_key']) )
        {
            #恢复团购库存

            $update1 = M(self::GROUPBUY_TABLE)->where([
                "id" => $groupBuyOrder['group_buy_id']
            ])->save([
                "buy_num" => ["exp","buy_num-".$groupBuyOrder['goods_num']],
                "update_time" => time()
            ]);

            #恢复商品库存
            $update2 = M(self::GOODS_TABLE)->where([
                "goods_id" => $groupBuyOrder['goods_id']
            ])->save([
                "store_count" => [
                    "exp", "store_count+".$groupBuyOrder['goods_num']
                ]
            ]);

        }else{
            #多规格
            $groupBuyModel = M(self::GROUPBUY_TABLE);
            $groupBuy = $groupBuyModel->where([
                "id" => $groupBuyOrder['group_buy_id'] 
            ])->find();
            $update1 = 1;
            $update2 = 1;
            $groupBuy['good_specs'] = json_decode($groupBuy['good_specs'],true);
            if( isset($groupBuy['good_specs'][$groupBuyOrder['spec_key']]) )
            {
                $spec_key = $groupBuy['good_specs'][$groupBuyOrder['spec_key']];
                $groupBuy['good_specs'][$spec_key]['buy_num'] =  $groupBuy['good_specs'][$spec_key]['buy_num'] + $groupBuyOrder['goods_num']; 

                $update1 = $groupBuyModel->where([
                    "id" => $groupBuyOrder['group_buy_id'] 
                ])->save([
                    "good_specs" => json_encode($groupBuy['good_specs'])
                ]);

                $update2 = M(self::GOODS_SPEC_TABLE)->where([
                    "goods_id" => $groupBuyOrder['goods_id'],
                    "key" => $groupBuyOrder['spec_key'] 
                ])->save([
                    "store_count" => [
                        "exp", "store_count+".$groupBuyOrder['goods_num']
                    ]
                ]);
            }
        }  

        if( FALSE !== $update1 && FALSE !== $update2 )
        {
            return TRUE;
        }

        return FALSE;
        
    }

    /**
     * 团购检查，时间到期时检查，符合的自动成团，不符合的自动解散
     * @param $groupbuy_id int
     * @return mix
     */ 
    public static function checkGroupBuy($groupbuy_id = NULL)
    {
        $model = M(self::GROUP_INFO_TABLE);

        $where = [
            "end_time" => ["lt",time()],
            "status" => 0,
        ];

        if( $groupbuy_id )
        {
            $where['group_buy_id'] = $groupbuy_id;
        }

        $groups = $model->where($where)->select();

        $updateForSuccess = [];
        $updateForFailed = [];

        foreach($groups as $k => $v)
        {
            if( $v['per_num'] >= $v['member_num'] )
            {
                $updateForSuccess[] = $v['id'];
            }else{
                $updateForFailed[] = $v['id'];
            }
        }

        $result = [
            "updateForSuccess" => $updateForSuccess,
            "updateForFailed" => $updateForFailed,
        ];

        if( !empty($updateForSuccess) )
        {
            $result['success'] = $model->where([
                "id" => ["IN",implode(",",$updateForSuccess)]
            ])->save([
                "status" => 1
            ]);
        }

        if( !empty($updateForFailed) )
        {
            $result['failed'] = self::detoryGroup($updateForFailed,"未成团，团购退款");
        }
        
        return $result;
    }


    /**
     * 团购解散（已经支付过的，但是不成团）
     * @param $group_info_id int/array
     * @return mix
     */ 
    public static function detoryGroup($group_info_id = 0,$reason = '未成团，团购退款')
    {
        if( !$group_info_id  ){
            return false;
        }

        if( is_array($group_info_id) )
        {
            $res = [];
            foreach( $group_info_id as $v )
            {
                $res[] = self::detoryGroup($v);
            }

            return $res;
        }

        $orders = M(self::GROUP_ORDER_TABLE)->where([
            "group_info_id" => $group_info_id,
            "status" => 1
        ])->select();

        if( !empty($orders) )
        {
            foreach( $orders as $k => &$v )
            {
                #退款
                $result = self::refund( $v, $reason );
            }
        }

        if( !$orders )
        {
            $update =  M(self::GROUP_INFO_TABLE)->where([
                "id" => $group_info_id
            ])->save([
                "status" => 2,
                "update_time" => time()
            ]);

            return $update === FALSE ? 0 : $group_info_id; 
        }
        doLog("[destory]\r\n[group_info_id]{$group_info_id}\r\n[res]".json_encode($res),"destory_groupbuy");
        return $res;
        
    }

    /**
     * 退款
     * @param $groupBuyOrder groupBuyOrder\groupBuyOrder / int
     * @return false/result;
     */
    public static function refund($groupBuyOrder,$reason = "")
    {
        if( is_numeric($groupBuyOrder) )
        {
            $groupBuyOrder = M(self::GROUP_ORDER_TABLE)->where([
                "id" => $groupBuyOrder
            ])->find();
        }

        if( empty($groupBuyOrder) )
        return false;

        #执行退款指令
        #系统订单退款
        try{
            $RefundLogic = new \Common\Logic\RefundLogic;
            $refund =  $RefundLogic ->createRefund($groupBuyOrder['order_sn'],"all", $reason );
        }catch(\Exception $e)
        {

            return false;
        }
        return $refund;
    }

    /**
     * 退款回调
     * @param order_sn
     * @param refund_sn
     * @param amount 元
     * @return bool
     * */
    public static function refundCallback($result)
    {
        if( !$result || !isset($result['order_sn']) || empty($result['order_sn']) )
            return false;

        #给团购订单标记为退款
        $update = M(self::GROUP_ORDER_TABLE)->where([
            "order_sn" => $result['order_sn']
        ])->save([
            "status" => 3,
            "update_time" => time()
        ]);
        
        if( $update === false )
        {
            return false;
        }

        #恢复库存
        $buyOder = M(self::GROUP_ORDER_TABLE)->where([
            "order_sn" => $result['order_sn']
        ])->find();
        self::rebackStore($buyOder);

        return true;
    }

    /**
     * 生成支付订单
     * @param $group_id int
     * @param $cacl_price bool 是否仅仅计算价格
     * @return mix false/ orderInfo
     */ 
    protected static function genratePayOrder( $param, $cacl_price = false)
    {
        // "groupBuyInfo" => $item,
        // "spec_key" => $param['spec_key'],
        // "num" => $param['num'],
        // "user_id" => $param['user_id'],
        // "address_id" => $param['address_id'],
        // "invoice_title" => $param['invoice_title'],
        // "user_note" => $param['user_note'],
        if( empty($param['num']) )
            throw new Exception("商品数量未选择",-1);

        if( !empty( $param['spec_key'] ) )
        {
            $goods_price = bcmul( $param['num'], $param['groupBuyInfo']['good_specs'][$param['spec_key']]['price'] , 2 );
        }else{
            $goods_price = bcmul( $param['num'], $param['groupBuyInfo']['price'], 2 );
        }

        // var_dump( $param['num'], $param['groupBuyInfo']['good_specs'][$param['spec_key']]['price']);
        // var_dump($param);

        if( bccomp(  0, $goods_price, 2 ) >= 0 )
        {
            throw new Exception("系统错误，请稍后重试",-3);
        }

        #如果仅仅是计算价格，返回商品价格
        if( $cacl_price )
            return $goods_price;
        #解析地址
        $address = self::parseAddress( $param['address_id'], $param['user_id']);

        #order_sn 组成 M年月日时分秒4
        $order = [];
        $order['is_groupbuy'] = 1;
        $order['parent_sn'] = $order['order_sn'] = self::createORderSn();
        $order['user_id'] = $param['user_id'];
        $order['order_status'] = 0;
        $order['shipping_status'] = 0;
        $order['pay_status'] = 0;
        $order['email'] = '';
        $order['shipping_code'] = '';#物流Code
        $order['shipping_name'] = '';
        $order['pay_code'] = '';
        $order['pay_name'] = '';
        $order['invoice_title'] = $param['invoice_title'];#发票抬头
        $order['goods_price'] = $goods_price;#商品总金额
        $order['shipping_price'] = self::getShipingPrice( $param['groupBuyInfo']['goods_id'],$param['num'],$goods_price );#运费
        $order['order_amount'] = bcadd( $goods_price, $order['shipping_price'], 2 );#应付款
        $order['total_amount'] = $order['order_amount'];#订单总金额
        $order['add_time'] = time();
        $order['order_prom_id'] = $param['groupBuyInfo']['id'];
        $order['user_note'] = $param['user_note'];
        $order['admin_note'] = '';
        $order['shop_id'] = $param['groupBuyInfo']['shop_id'];
        $order['total_buy_number'] = $param['num'];

        $order = array_merge( $order, $address );

        $add = M(self::ORDER_TABLE)->add($order);

        if( !$add )
            throw new Exception("订单创建失败",-4);

        $order['id'] = $add;

        #写入order_good
        $goodsInfo = [];

        $goods = M(self::GOODS_TABLE)->where([
            "goods_id" => $param['groupBuyInfo']['goods_id']
        ])->find();

        $goodsInfo['order_id'] = $add;
        $goodsInfo['goods_id'] = $goods['goods_id'];
        $goodsInfo['goods_name'] = $goods['goods_name'];
        $goodsInfo['goods_sn'] = $goods['goods_sn'];
        $goodsInfo['goods_num'] = $param['num'];
        $goodsInfo['market_price'] = $goods['market_price'];
        $goodsInfo['goods_price'] = bcdiv( $goods_price , $param['num'], 2);#写入团购价
        $goodsInfo['cost_price'] = $goods['cost_price'];
        $goodsInfo['give_integral'] = $goods['give_integral'];
        $goodsInfo['spec_key'] = $param['spec_key'];
        $goodsInfo['spec_key_name'] = '';
        if( !empty($goodsInfo['spec_key']) )
        {
            $getSpecs = self::getSpecs( $goodsInfo['goods_id'], $goodsInfo['spec_key']);
            $goodsInfo['spec_key_name'] = $getSpecs ? $getSpecs['key_name']:'';
            #减库存
            if(  $getSpecs['store_count'] < $param['num'] )
            {
                throw new Exception("库存不足",-2);
            }
            $reduce = M(self::GOODS_SPEC_TABLE)->where([
                "goods_id" => $getSpecs['goods_id'],
                "key" => $getSpecs['key']
            ])->save([
                "store_count" => ["exp","store_count-".$param['num']]
            ]);
        }else{
            #减库存
            if(  $goods['store_count'] < $param['num'] )
            {
                throw new Exception("库存不足",-3);
            }
            $reduce = M(self::GOODS_TABLE)->where([
                "goods_id" => $goodsInfo['goods_id']
            ])->save([
                "store_count" => ["exp","store_count-".$param['num']]
            ]);
        }
        $goodsInfo['bar_code'] = '';
        $goodsInfo['prom_type'] = 2;
        $goodsInfo['prom_id'] = $param['groupBuyInfo']['id'];
        $goodsInfo['order_sn'] = $order['order_sn'];

        if( $reduce === FALSE )
        {
            throw new Exception("创建订单失败",-5);
        }

        $addInfo = M(self::ORDERGOODS_TABLE)->add($goodsInfo);

        if( !$addInfo )
        {
            throw new Exception("创建订单失败",-6);
        }

        #订单日志
        order_log($order['order_sn'], '', '提交订单', 1);
        order_log($order['order_sn'], '', '减少库存成功', 1);
 
        return $order;
    }

    /**
     * 记录团购订单
     * @param $grouo int
     * @return mix
     */ 
    protected static function genrateGroupOrder($param)
    {
        // "groupBuyInfo" => $item,
        // "orderInfo" => $orderInfo,
        // "spec_key" => $param['spec_key'],
        // "num" => $param['num'],
        // "user_id" => $param['user_id'],
        $model = M(self::GROUP_ORDER_TABLE);

        $now = time();

        $order = $model->add([
            "group_buy_id" => $param['groupBuyInfo']['id'],
            "group_info_id" => 0,
            "order_sn" => $param['orderInfo']['order_sn'],
            "goods_id" => $param['groupBuyInfo']['goods_id'],
            "spec_key" => $param['spec_key'],
            "goods_num" => $param['num'],
            "user_id" => $param['user_id'],
            "status" => 0,
            "create_time" => $now,
            "join_group_time" => 0,
            "update_time" => $now,
        ]);
        
        return $order;
    }

    /** 
    * 解析用户的地址
    **/ 
    protected static function parseAddress($address_id,$user_id)
    {
        $model = M(self::ADDRESS_TABLE);

        $address = $model->where([
            "address_id" => $address_id
        ])->find();

        if( !$address )
            throw new Exception("地址选择无效",-1);

        return [
            "consignee" => $address['consignee'],
            "email" => $address['email'],
            "country" => $address['country'],
            "province" => $address['province'],
            "city" => $address['city'],
            "district" => $address['district'],
            "twon" => $address['twon'],
            "address" => $address['address'],
            "zipcode" => $address['zipcode'],
            "mobile" => $address['mobile'],
            "province_name" => $address['province_name'],
            "city_name" => $address['city_name'],
            "district_name" => $address['district_name'],
            "twon_name" => $address['twon_name'],
        ];
    }

    /**
     * 获取商品的邮费
     * @param $goods_id
     */ 
    protected static function getShipingPrice( $goods_id,$goods_num,$goods_price = 0 )
    {
        $goods = M(self::GOODS_TABLE)->where([
            "goods_id" => $goods_id
        ])->field('goods_id,shop_id,weight,is_free_shipping,is_on_sale')->find();

        if( !$goods || 0 == $goods['is_on_sale'] )
            throw new Exception("商品已下架",-1);
        
        $goods_weight = 0;
        if($goods['is_free_shipping'] == 0){
            $goods_weight = $goods['weight'] * $goods_num; //累积商品重量 每种商品的重量 * 数量
        }else{
            return 0;
        }
        
        $money = \Common\Logic\FeeLogic::getPostFee($goods['shop_id'],$goods_weight,$goods_price);
        
        return $money;
    } 

    protected static function randNumber($len = 4){
        $chars = str_repeat('0123456789', 10);
        $chars = str_shuffle($chars);
        $str = substr($chars, 0, $len);
        return $str;
    }

    protected static function getSpecs($goods_id,$key = '')
    {
        $model = M(self::GOODS_SPEC_TABLE);

        $where = [
            "goods_id" => $goods_id,
        ];

        if( !empty($key) )
        {
            $where['key']  = $key;

            return $model->where($where)->find();
        }

        return $model->where($where)->select();
    }

    protected static function createORderSn()
    {  
        return "M".date("YmdHis").self::randNumber(4);
    }
}